package com.wx.network.handler;

import com.wx.cache.ResponseCache;
import com.wx.content.DataType;
import com.wx.network.codec.RpcProtocol;
import com.wx.network.mesg.Response;
import com.wx.util.SerializationUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RpcClientHandler extends SimpleChannelInboundHandler<RpcProtocol> {
    /**
     * 获得从服务器返回的数据
     * @param channelHandlerContext
     * @param rpcProtocol
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcProtocol rpcProtocol) throws Exception {
        byte[] responseData = rpcProtocol.getData();
        Response response = SerializationUtil.unSerialzationObj(responseData, Response.class);
        //todo 把响应数据返回给调用发起方
        if(response.getDataType().equals(DataType.PANG)){
            new PangHeartBeatHandler().handleData(channelHandlerContext,response);
        }else if (response.getDataType().equals(DataType.BUSSINESS)){
            Object result = response.getResult();
            log.info("放入返回结果缓存id{},内容{}",response.getRequestId(),result);
            ResponseCache.putResult(response.getRequestId(),result);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("{}调用发生异常，原因{}",ctx.channel().remoteAddress(),cause.getMessage());
    }
    /**
     * 心跳监测，如果四秒管道没有触发读事件就断开连接
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event=(IdleStateEvent)evt;
            switch (event.state()){
                case ALL_IDLE:
                    //发送心跳包
                    new PangHeartBeatHandler().sendHeartBeat(ctx);
                    break;
                default:
                    break;
            }
        }
        super.userEventTriggered(ctx, evt);
    }
}
